<?php

namespace App\Controller;

use Cake\Cache\Cache;
use Dm\Request\V20151123\SingleSendMailRequest;
use Cake\Core\Configure;
use Cake\Collection\Collection;

class AdminsController extends AppController
{

  public function initialize()
  {
    parent::initialize();
  }

  /*
   * create by phpstorm
   * author：Ming
   * date：2018.10.30
   * ps：新建用户
   * */
  public function add()
  {
    if(!$this->request->is("post")) {
      $this->G->error("post_error");
      return null;
    }
    $email = $this->request->getData("email");
    $password = $this->request->getData("password");
    $user_type = $this->request->getData("user_type");
    $store_id = $this->request->getData("store_id");
    $truename = trim($this->request->getData("truename"));
    $intro = $this->request->getData("intro");
    $head_img = $this->request->getData("head_img");
    $position = $this->request->getData("position");
    $order_num = $this->request->getData("order_num");
    if(empty($email) || !preg_match("/^[\.a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/i", $email)) {
      $this->G->error("email_error");
      return null;
    }
    if(empty($password) || strlen($password) !== 32) {
      $this->G->error("password_error");
      return null;
    }
    if(empty($user_type)) {
      $this->G->error("user_type_error");
      return null;
    }
    if(empty($truename) || mb_strlen($truename) > 40) {
      $this->G->error("truename_error");
      return null;
    }
    if($position !== 'leader' && $position !== 'arl' && $position !== 'sm' && $position !== 'staff') {
      $this->G->error("position_error");
      return null;
    }
    if(!empty($order_num)) {
      if(!is_numeric($order_num)) {
        $this->G->error("order_num_error");
        return null;
      }
    }
    if(!empty($store_id)) {
      if(!is_numeric($store_id)) {
        $this->G->error("store_id_error");
        return null;
      }
      $this->loadModel('Stores');
      $stores = $this->Stores->findById($store_id)->select(['id'])->first();
      if(empty($stores)) {
        $this->G->error("store_id_error");
        return null;
      }
    }
    $emails = $this->Users->findByEmail($email)->select(['id'])->first();
    if(!empty($emails)) {
      $this->G->error("email_exist");
      return null;
    }
    $user = $this->Users->newEntity();
    if(!empty($intro)) {
      $this->loadComponent('ContentFormat');
      $result = $this->ContentFormat->clean($intro, 1);
      $user->intro = $result[0];
    }
    $salt = rand(100000, 999999);
    $password = md5($password . $salt);
    $username = $this->str_rand();
    $user->username = $username;
    $user->password = $password;
    $user->email = $email;
    $user->user_type = $user_type;
    $user->enabled = 1;
    $user->salt = $salt;
    $user->truename = $truename;
    $user->store_id = $store_id;
    $user->head_img = $this->G->setImgUrl($head_img);
    $user->position = $position;
    $user->order_num = $order_num;
    $this->Users->save($user);
    $this->G->success('success');
  }


  /*
   * create by phpstorm
   * author：Ming
   * date：2018.10.30
   *  @param int    $id     修改的用户的id
   * ps：修改用户
   * */
  public function update($id = null)
  {
    if(!$this->request->is("post")) {
      $this->G->error("post_error");
      return null;
    }
    if(!is_numeric($id)) {
      $this->G->error("id_error");
      return null;
    }
    $email = $this->request->getData("email");
    $password = $this->request->getData("password");
    $user_type = $this->request->getData("user_type");
    $store_id = $this->request->getData("store_id");
    $truename = trim($this->request->getData("truename"));
    $intro = $this->request->getData("intro");
    $head_img = $this->request->getData("head_img");
    $position = $this->request->getData("position");
    $order_num = $this->request->getData("order_num");
    if(empty($email) || !preg_match("/^[\.a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/i", $email)) {
      $this->G->error("email_error");
      return null;
    }
    if(empty($user_type)) {
      $this->G->error("user_type_error");
      return null;
    }
    if(empty($truename) || mb_strlen($truename) > 40) {
      $this->G->error("truename_error");
      return null;
    }
    if($position !== 'leader' && $position !== 'arl' && $position !== 'sm' && $position !== 'staff') {
      $this->G->error("position_error");
      return null;
    }
    if(!empty($order_num)) {
      if(!is_numeric($order_num)) {
        $this->G->error("order_num_error");
        return null;
      }
    }
    $users = $this->Users->findById($id)->select(['id'])->first();
    if(empty($users)) {
      $this->G->error("user_not_found");
      return null;
    }
    if(!empty($store_id)) {
      if(!is_numeric($store_id)) {
        $this->G->error("store_id_error");
        return null;
      }
      $this->loadModel('Stores');
      $stores = $this->Stores->findById($store_id)->select(['id'])->first();
      if(empty($stores)) {
        $this->G->error("store_id_error");
        return null;
      }
    }
    $emails = $this->Users->findByEmail($email)->where(['id !=' => $id])->select(['id'])->first();
    if(!empty($emails)) {
      $this->G->error("email_exist");
      return null;
    }
    $user = $this->Users->newEntity();
    if(!empty($password)) {
      if(strlen($password) !== 32) {
        $this->G->error("password_error");
        return null;
      }
      $salt = rand(100000, 999999);
      $password = md5($password . $salt);
      $user->password = $password;
      $user->salt = $salt;
    }
    if(!empty($intro)) {
      $this->loadComponent('ContentFormat');
      $result = $this->ContentFormat->clean($intro, 1);
      $user->intro = $result[0];
    }
    $user->id = $id;
    $user->email = $email;
    $user->user_type = $user_type;
    $user->truename = $truename;
    $user->store_id = $store_id;
    $user->head_img = $this->G->setImgUrl($head_img);
    $user->position = $position;
    $user->order_num = $order_num;
    $this->Users->save($user);
    $this->G->success('success');
  }

  /*
   * create by phpstorm
   * author：Ming
   * date：2018.10.30
   * ps：删除用户
   * */
  public function delete()
  {
    if(!$this->request->is("post")) {
      $this->G->error("post_error");
      return null;
    }
    $ids = $this->request->getData("ids");
    if(empty($ids) || !is_array($ids)) {
      $this->G->error("ids_error");
      return null;
    }
    $users = $this->Users->find()
      ->select(['id'])
      ->where(['id in' => $ids])
      ->toArray();
    if(!empty($users)) {
      $this->Users->deleteAll(['id in' => $ids]);
    }
    $this->G->success("success");
  }

  /*
   * create by phpstorm
   * author：Ming
   * date：2018.10.30
   * @param int    $id     获取信息的用户的id
   * ps：获取用户信息
   * */
  public function view($id = null)
  {
    if(!is_numeric($id)) {
      $this->G->error("id_error");
      return null;
    }
    $users = $this->Users->findById($id)->first();
    if(empty($users)) {
      $this->G->error("user_not_found");
      return null;
    }
    $this->loadModel('Stores');
    $stores = $this->Stores->findById($users['store_id'])->select(['title'])->first();
    $list = [];
    $list['email'] = $users['email'];
    $list['user_type'] = $users['user_type'];
    $list['store_id'] = $users['store_id'];
    $list['truename'] = $users['truename'];
    if(!empty($users['intro'])) {
      $this->loadComponent('ContentFormat');
      $users['intro'] = $this->ContentFormat->add($users['intro']);
    }
    $list['intro'] = $users['intro'];
    $list['head_img'] = $this->G->getImgUrl($users['head_img']);
    $list['position'] = $users['position'];
    $list['order_num'] = $users['order_num'];
    $list['store_name'] = empty($stores['title']) ? '' : $stores['title'];
    $this->G->success("success", $list);
  }

  /*
   * create by phpstorm
   * author：Ming
   * date：2018.10.30
   * @param string    $act     (enabled,disabled),设置用户是否可用
   * ps：设置用户状态
   * */
  public function setstatus($act = null)
  {
    if(!$this->request->is("post")) {
      $this->G->error("post_error");
      return null;
    }
    $ids = $this->request->getData("ids");
    if(empty($ids) || !is_array($ids)) {
      $this->G->error("ids_error");
      return null;
    }
    if($act !== 'enabled' && $act !== 'disabled') {
      $this->G->error("act_error");
      return null;
    }
    $act = $act === 'enabled' ? 1 : 0;
    $this->Users->query()
      ->update()
      ->set(["enabled" => $act])
      ->where(['id in' => $ids])
      ->execute();
    $this->G->success("success");
  }

  /*
   * create by phpstorm
   * author：Ming
   * date：2018.10.30
   * @param int    $page     当前页
   * ps：获取用户列表
   * */
  public function index($page = null)
  {
    if(!is_numeric($page)) {
      $this->G->error("page_error");
      return null;
    }
    $username = $this->request->getData("username");
    $enabled = $this->request->getData("enabled");
    $truename = $this->request->getData("truename");
    $group_id = $this->request->getData("group_id");
    $array_where = [];
    if(is_numeric($enabled)) {
      $array_where['enabled'] = $enabled;
    }
    if(!empty($truename)) {
      $array_where['truename like '] = '%' . $truename . '%';
    }
    if(!empty($username)) {
      $array_where['username like '] = '%' . $username . '%';
    }
    if(!empty($group_id)) {
      $array_where['group_id'] = $group_id;
    }
    $this->loadModel('Groups');
    $groups = $this->Groups->find()
      ->select(['id', 'alias'])
      ->toArray();
    $group = [];
    foreach ($groups as $k => $v) {
      $group[$v['id']] = $v['alias'];
    }
    $limit = 30;
    $admins = $this->Admins->find()
      ->where($array_where)
      ->order(['id desc'])
      ->limit($limit)->page($page);
    $count = $admins->count();
    $admins = $admins->toArray();
    $list['list'] = [];
    if(!empty($admins)) {
      foreach ($admins as $k => $v) {
        $admins[$k]['group'] = $group[$v['group_id']];
        $list['list'][] = $admins[$k];
      }
    }
    $lastPage = ceil($count / $limit);
    if($lastPage >= 5) {
      $list['pageTotal'] = 5;
    } elseif($lastPage >= 0) {
      $list['pageTotal'] = $lastPage;
    } else {
      $list['pageTotal'] = 0;
    }
    $list['page'] = $page;
    $this->G->success('Success', $list);
  }

  /*
   * create by phpstorm
   * author：Ming
   * date：2018.10.30
   * ps：登录
   * */
  public function login()
  {
    if(!$this->request->is("post")) {
      $this->G->error("post_error");
      return null;
    }
    $admin_pe = $this->Admins->newEntity();
    $username = $this->request->getData("username");
    $password = $this->request->getData("password");
    $admin = $this->Admins->find()
      ->select(["id", "username", "truename", "password", "group_id", "locked", 'visit_count'])
      ->where(["username" => $username, "enabled" => 1])
      ->first();
    if(!$admin) {
      $this->G->error("user_not_found");
      return null;
    }
    $id = $admin->id;
    $group_id = $admin->group_id;
    $locked = $admin->locked;
    $password_db = $admin->password;
    $username = $admin->username;
    $truename = $admin->truename;
    if($locked) {
      $this->G->error("user_disabled");
      return null;
    }
    $login_username_cache = Cache::read("admin_lock_" . $username, 'f1h');
    if($login_username_cache >= 5) {
      $this->G->error("admin_lock");
      return null;
    }
    if($password_db != $password) {
      if(empty($login_username_cache)) {
        Cache::write("admin_lock_" . $username, 1, 'f1h');
      } else {
        Cache::write("admin_lock_" . $username, ($login_username_cache + 1), 'f1h');
      }
      $this->G->error("password_error");
      return null;
    }
    if(!empty($login_username_cache)) {
      Cache::delete("admin_lock_" . $username, "f1h");
    }
    $jwt_create = [];
    $jwt_refresh_create = [];
    $jwt_create['user_id'] = $id;
    $jwt_create['gid'] = $group_id;
    $jwt = $this->Jwt->create($jwt_create);
    $jwt_refresh_create['user_id'] = $id;
    $jwt_refresh = $this->Jwt->create($jwt_refresh_create, '24 hours', 1);
    $admin_pe->visit_count = $admin->visit_count + 1;
    $admin_pe->last_login = time();
    $admin_pe->id = $id;
    $admin_pe->last_ip = $_SERVER['REMOTE_ADDR'];
    $admin_save = $this->Admins->save($admin_pe);
    $this->loadModel("Groups");
    $group_db = $this->Groups->findById($group_id)->select(['alias', 'acos'])->first();
    $acos_arr = $group_db["acos"];
    $alias = $group_db["alias"];
    $acos_arr = json_decode($acos_arr);
    //        $str_acos = "";
    //        if(!empty($acos_arr)){
    //            foreach ($acos_arr as $key => $value){
    //                if($key != 0){
    //                    $str_acos .= ",".$value;
    //                }else{
    //                    $str_acos .= $value;
    //                }
    //            }
    //        }
    if(!empty($acos_arr) || $group_id == 1) {
      $arr_where = [];
      $this->loadModel("Acos");
      if($group_id != 1) {
        $parent_ids = $this->Acos->find()
          ->select(["id", "parent_id"])
          ->where(['id in' => $acos_arr])
          ->order(['lft asc'])
          ->toArray();
        $acos_arr = array_merge(array_column($parent_ids, 'parent_id'), $acos_arr);
        $arr_where["id in"] = $acos_arr;
        $arr_where["status"] = "enabled";
      } else {
        $arr_where["status"] = "enabled";
      }
      $acos = $this->Acos->find()
        ->select(["id", "title" => "alias", 'status', "parent_id", 'img' => "icon", "path" => "link"])
        ->where($arr_where)
        ->order(['lft asc'])
        ->toArray();
      $collection = new Collection($acos);
      $acos1 = $collection->nest('id', 'parent_id')->toList();
    } else {
      $acos1 = [];
    }
    //        $acos_new = array();
    //        $acos1 = [];
    //        if(!empty($acos)){
    //            foreach ($acos as $key => $value){
    //                $acos_new[] = $value['parent_id'];
    //            }
    //            $acos_new = array_unique($acos_new);
    //            $acos_new = array_values($acos_new);
    //            $acos1 = $this->Acos->find()
    //                ->select(["id","title"=>"alias",'status','img'=>"icon"])
    //                ->where(['id in'=>$acos_new, 'status'=>'enabled'])
    //                ->order(['lft asc'])
    //                ->toArray()
    //            ;
    //            if($acos1){
    //                foreach ($acos1 as $key1 => $value1){
    //                    foreach ($acos as $k=>$v){
    //                        if($value1["id"] == $v["parent_id"]) {
    //                            if(empty($acos1[$key1]["children"])){
    //                                $acos1[$key1]["children"] = array();
    //                            }
    //                            unset($acos[$k]['id']);
    //                            unset($acos[$k]['parent_id']);
    //                            $acos1[$key1]["children"][] = $v;
    //                        }
    //                    }
    //                    unset($acos1[$key1]['id']);
    //                }
    //                $acos1 = array_values($acos1);
    //            }
    //        }
    if($admin_save) {
      $this->loadModel('AdminLoginLogs');
      $admin_login_log = $this->AdminLoginLogs->newEntity();
      $admin_login_log->admin_id = $id;
      $admin_login_log->ip = $this->request->clientIp();
      $this->AdminLoginLogs->save($admin_login_log);
      $this->G->success("Success", ['uid' => $id, 'username' => $username, 'truename' => $truename, 'group' => $alias, 'jwt' => $jwt, 'jwt_refresh' => $jwt_refresh, 'acos' => $acos1]);
    }
  }


  public function info()
  {
    $memo = [
      'uid'      => 1,
      'username' => 'admin',
      'truename' => '',
      'group'    => '超级管理员',
      'acos'     => [
        [
          "id"        => 1,  // 菜单id
          "title"     => "", // 菜单标题
          "status"    => "enabled", // 菜单状态
          "parent_id" => 0, // 菜单父id
          "img"       => "", // 菜单icon
          "path"      => "/icon", // 菜单路径
          "component" => "",  // 菜单组件 父菜单无需组件 如需多框架结构可设置对应主题
          "roles"     => [], // 页面权限
          "redirect"  => "/icon/index", // 重定向路径 如多二级菜单，当路径为顶级菜单时会跳转到对应二级菜单
          "children"  => [
            [
              'id'        => 2,
              'title'     => '图标',
              "img"       => 'icon',
              "path"      => 'index',
              "parent_id" => 1,
              "status"    => 'enabled',
              "component" => "Icons",
              "roles"     => ['list', 'add', 'update', 'delete', 'info'],
            ],
          ], // 二级菜单
        ],
        [
          "id"        => 3,
          "title"     => "",
          "status"    => "enabled",
          "parent_id" => 0,
          "img"       => "",
          "path"      => "/external-link",
          "component" => "",
          "roles"     => [],
          "children"  => [
            [
              'id'        => 4,
              'title'     => '跳转外链',
              "img"       => 'link',
              "path"      => 'http://baidu.com/',
              "parent_id" => 3,
              "status"    => 'enabled',
              "component" => "",
              "roles"     => [],
            ],
          ],
        ],
      ],
    ];

    $this->G->success("Success", $memo);
  }

  public function logout()
  {
    $this->G->success("Success");
  }


  /*
   * create by phpstorm
   * author：Ming
   * date：2020.02.17
   * ps：用户修改自己的密码
   * */
  public function updatepassword()
  {
    if(!$this->request->is("post")) {
      $this->G->error("post_error");
      return null;
    }
    $password = $this->request->getData("password");
    if(empty($password) || strlen($password) !== 32) {
      $this->G->error("password_error");
      return null;
    }
    $uid = $this->Jwt->get('user_id');
    $users = $this->Admins->findById($uid)->first();
    if(empty($users)) {
      $this->G->error("user_not_found");
      return null;
    }
    $user = $this->Admins->newEntity();
    $user->id = $users['id'];
    $user->password = md5($password);
    $this->Admins->save($user);
    $this->G->success("success");
  }

  /*
   * create by phpstorm
   * author：Ming
   * date：2018.10.31
   * ps：发送邮件验证码
   * */
  public function sendcode()
  {
    if(!$this->request->is("post")) {
      $this->G->error("post_error");
      return null;
    }
    $email = $this->request->getData("email");
    if(empty($email) || !preg_match("/^[\.a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/i", $email)) {
      $this->G->error("email_error");
      return null;
    }
    $users = $this->Users->findByEmail($email)->first();
    if(empty($users)) {
      $this->G->error("email_not_found");
      return null;
    }
    $send_email_num = Cache::read('send_email_num', 'f1d');
    if(!empty($send_email_num)) {
      if(date("Ymd") == date("Ymd", $send_email_num['date'])) {
        if($send_email_num['total'] > 200) {
          $this->G->error("email_send_limit");
          return null;
        }
      }
    }
    $forget_password = Cache::read('forget_password_' . $email, 'f10m');
    if(!empty($forget_password)) {
      if($forget_password['time'] + 60 > time()) {
        $this->G->error("wait_" . (time() - $forget_password['time']) . '_seconds');
        return null;
      }
    }
    $code = rand(100000, 999999);
    Cache::write('forget_password_' . $email, ['code' => $code, 'time' => time()], 'f10m');
    $this->sendMail($email, 'Please check your verification code.', 'Your verification code is:' . $code);
    if(!empty($send_email_num)) {
      Cache::write('send_email_num', ['total' => $send_email_num['total'] + 1, 'date' => time()], 'f1d');
    } else {
      Cache::write('send_email_num', ['total' => 1, 'date' => time()], 'f1d');
    }
    $this->G->success('success');
  }

  /*
   * create by phpstorm
   * author：Ming
   * date：2018.10.31
   * ps：通过邮件验证码更改密码
   * */
  public function code2password()
  {
    if(!$this->request->is("post")) {
      $this->G->error("post_error");
      return null;
    }
    $email = $this->request->getData("email");
    $password = $this->request->getData("password");
    $code = $this->request->getData("code");
    if(empty($email) || !preg_match("/^[\.a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/i", $email)) {
      $this->G->error("email_error");
      return null;
    }
    if(empty($password) || strlen($password) !== 32) {
      $this->G->error("password_error");
      return null;
    }
    $users = $this->Users->findByEmail($email)->first();
    if(empty($users)) {
      $this->G->error("email_not_found");
      return null;
    }
    if($users['enabled'] !== 1) {
      $this->G->error("user_disabled");
      return null;
    }
    $forget_password = Cache::read('forget_password_' . $email, 'f10m');
    if(empty($forget_password)) {
      $this->G->error("code_disabled");
      return null;
    }
    if($code !== $forget_password['code']) {
      $this->G->error("code_error");
      return null;
    }
    $user = $this->Users->newEntity();
    $user->id = $users['id'];
    $user->password = md5($password . $users['salt']);
    $this->Users->save($user);
    $this->G->success("success");
  }

  /*
  * create by phpstorm
  * author：Ming
  * date：2018.11.10
  * ps：通过jwt_refresh获取新的jwt
  * */
  public function jwtrefresh()
  {
    $uid = $this->Jwt->get("user_id");
    $users = $this->Users->find()
      ->where(['id' => $uid])
      ->select(['id', 'enabled', 'user_type'])
      ->first();
    if(!$users) {
      $this->G->error("user_not_found");
      return null;
    }
    $enabled = $users->enabled;
    if($enabled == 0) {
      $this->G->error("auth_error");
      return null;
    }
    $user_type = $users->user_type;
    $jwt_create = [];
    $jwt_create['user_id'] = $uid;
    $jwt_create['user_type'] = $user_type;
    $jwt = $this->Jwt->create($jwt_create, '24 hours');
    $jwt_refresh = $this->Jwt->create($jwt_create, '168 hours', 1);
    $list = [];
    $list["jwt"] = $jwt;
    $list["jwt_refresh"] = $jwt_refresh;
    $this->G->success('Success', $list);
  }

  /*
  * 生成随机字符串
  * @param int $length 生成随机字符串的长度
  * @param string $char 组成随机字符串的字符串
  * @return string $string 生成的随机字符串
  */
  private function str_rand($length = 16, $char = '0123456789abcdefghijklmnopqrstuvwxyz')
  {
    if(!is_int($length) || $length < 0) {
      return false;
    }
    for ($n = 1; $n > 0; $n--) {
      $string = '';
      for ($i = $length; $i > 0; $i--) {
        $string .= $char[mt_rand(0, strlen($char) - 1)];
      }
      $selectresult = $this->Users->findByUsername($string)->select(['id'])->first();
      if(!empty($selectresult)) {
        $n++;
      }
    }

    return $string;
  }

  /*
  * 发送邮件
  * @param string $email  目标地址
  * @param string $subject  邮件主题
  * @param string $body  邮件正文
  */
  private function sendMail($email = null, $subject = null, $body = null)
  {
    $config_email = Configure::read('Aliemail');
    $region = $config_email['region'];
    $accessKey = $config_email['accessKey'];
    $accessSecret = $config_email['accessSecret'];
    $accountName = $config_email['accountName'];
    $fromAlias = $config_email['fromAlias'];
    $tag = $config_email['tag'];
    $iClientProfile = \DefaultProfile::getProfile($region, $accessKey, $accessSecret);

    $client = new \DefaultAcsClient($iClientProfile);
    $request = new SingleSendMailRequest();

    $request->setAccountName($accountName);
    $request->setFromAlias($fromAlias);
    $request->setAddressType(1);
    $request->setTagName($tag);
    $request->setReplyToAddress("true");
    $request->setToAddress($email);
    $request->setSubject($subject);
    $request->setHtmlBody($body);

    try {
      $response = $client->getAcsResponse($request);
      pr($response);
    } catch (\ClientException  $e) {
      pr($e->getErrorCode());
      pr($e->getErrorMessage());
    }
  }

}
